#include <qDebug>
#include <QFileInfo>
#include <QSettings>
#include "envclient.h"
#include "logger.h"
#include <rapidjson/document.h>
#include <rapidjson/stringbuffer.h>
#include <rapidjson/prettywriter.h>

void print_env_info(struct env_info & info)
{
    LOG(INFO)<< "left_plate = " << info.left_plate;
    LOG(INFO)<< "right_plate = " << info.right_plate;
    LOG(INFO)<< "left_line = " << info.left_line;
    LOG(INFO)<< "right_line = " << info.right_line;
    LOG(INFO)<< "left_back_line = " << info.left_back_line;
    LOG(INFO)<< "right_back_line = " << info.right_back_line;
    LOG(INFO)<< "people = " << info.people;
}

EnvClient::EnvClient()
{
    loadINI();
    pingger.init(localIP);
}

int EnvClient::init()
{
    if(true == mInited){
        return 0;
    }

    print_base_info();
    // 相机开完之后开启监听服务
    client.init(localPort, localIP);
    // 处理来自加油机器人的请求
    client.client_cb = std::bind(&EnvClient::recv_data, this, std::placeholders::_1, std::placeholders::_2);
    client.connect();
    mInited = true;
    return 0;
}

int EnvClient::recv_data(char* buf, size_t buf_size)
{
    memcpy(mData, buf, buf_size);
    mDataLen = buf_size;
    evtVar.notify();
    return 0;
}

void EnvClient::loadINI()
{
    QFileInfo fileInfo(CONFIG_FILE_PATH);
    if(fileInfo.isFile())
    {
        QSettings setting(CONFIG_FILE_PATH, QSettings::IniFormat);
        setting.setIniCodec("utf-8");

        localIP = setting.value("/EVN_MONITOR/serverIP").toString().toStdString();
        localPort  = setting.value("/EVN_MONITOR/serverPort").toInt();
    }
}

void EnvClient::print_base_info()
{
    LOG(INFO) << "localIP:" << localIP << std::endl;
    LOG(INFO) << "localPort:" << localPort << std::endl;
}

bool EnvClient::is_connected()
{
    return client.isConnected();
}


void EnvClient::parseEnvInfo(const char *data, int size)
{
    //qDebug("size = %d ", size);
    //qDebug() << data;
    rapidjson::Document dom;
    std::string jsonStr(data,size);
    if (dom.Parse(jsonStr.c_str()).HasParseError())
    {
        LOG(ERROR) << "JSON HasParseError\n";
        return;
    }

    if (dom.HasMember("left_plate") && dom["left_plate"].IsInt())
    {
        mInfo.left_plate = dom["left_plate"].GetInt();
    }
    if (dom.HasMember("right_plate") && dom["right_plate"].IsInt())
    {
        mInfo.right_plate = dom["right_plate"].GetInt();
    }

    if (dom.HasMember("left_line") && dom["left_line"].IsInt())
    {
        mInfo.left_line = dom["left_line"].GetInt();
    }
    if (dom.HasMember("right_line") && dom["right_line"].IsInt())
    {
        mInfo.right_line = dom["right_line"].GetInt();
    }
    if (dom.HasMember("left_back_line") && dom["left_back_line"].IsInt())
    {
        mInfo.left_back_line = dom["left_back_line"].GetInt();
    }
    if (dom.HasMember("right_back_line") && dom["right_back_line"].IsInt())
    {
        mInfo.right_back_line = dom["right_back_line"].GetInt();
    }
    if (dom.HasMember("people") && dom["people"].IsInt())
    {
        mInfo.people = dom["people"].GetInt();
    }

}

//@返回值：
//0:正常
//-1: 通讯故障
//-2: 有人
//-3: 压线
int EnvClient::check_info(int side)
{
    int bRet = 0;
    //1、组织json  //{"method":"GetEnvInfo","Side":"B"}
    rapidjson::StringBuffer strBuf;
    rapidjson::Writer<rapidjson::StringBuffer> writer(strBuf);

    writer.StartObject();
    writer.Key("method");
    writer.String("GetEnvInfo");
    writer.Key("Side");
    if(CHARGE_LEFT_SIDE==side){
        writer.String("A");
    }else{
        writer.String("B");
    }
    writer.EndObject();
    std::string jsonStr = strBuf.GetString();

    //2、发送
    evtVar.m_flag = false;
    client.sendMsg(jsonStr);
    //3、阻塞接收
    if(false ==  evtVar.m_flag){
        int nRet = evtVar.wait(1000*30);
        if(nRet){
            print_base_info();
            LOG(ERROR)<<"evtVar wait out of time";
            return -1;
        }
    }


    //4、解析判断
    parseEnvInfo(mData, mDataLen);
    print_env_info(mInfo);
    if(mInfo.people){
        bRet = -2;
    }else{
        if(CHARGE_LEFT_SIDE == side){
            if(mInfo.left_line == 0 && (mInfo.left_plate ==1 ||mInfo.left_back_line ==1 )){
                bRet = 0;
            }else{
                bRet = -3;
            }

        }else{
            if(mInfo.left_line == 0 && (mInfo.left_plate ==1 ||mInfo.left_back_line ==1 )){
                bRet = 0;
            }else{
                bRet = -3;
            }
        }
    }
    return bRet;
}

